home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-12-06 | 13.3 KB | 550 lines | [TEXT/ttxt] |
- class ListSelection (TwoDShape)
- class variables
- fill:(new Brush color:BlackColor)
- instance vars
- _descent
- class methods
- method afterInit self #rest args -> (
- apply nextMethod self args
- ListSelection.fill.inkMode := @srcXor
- )
- end
-
- ------------------------
-
- method init self { class ListSelection } #rest args #key \
- width:(10) ->
- (
- local height := 10
- local bounds := new Rect x2:width y2:height
- apply NextMethod self boundary:bounds fill:ListSelection.fill args
- )
-
- method afterInit self {class ListSelection } #rest args #key \
- font:(theSystemFont) \
- parent: ->
- (
- apply NextMethod self args
- changeFont self font 1
- if (not (isAKindOf parent TwoDPresenter)) do
- report BadParameter "parent must be a TwoDPresenter!"
- ThreadCriticalUp()
- local subs := parent.subPresenters
- if (subs = undefined) then
- parent.subPresenters := #(self)
- else
- prepend subs self
- self.presentedBy := parent
- ThreadCriticalDown()
- )
-
- method changeFont self {class ListSelection} font theLine ->
- (
- self.height := font.leading
- self._descent := font.descent - 2 -- frame offset
- selectLine self theLine @dontAction
- )
-
- method selectLine self {class ListSelection} the_line doAction ->
- (
- self.y := self.height * (the_line - 1) + self._descent
- )
-
- -----------------
-
- class ListBox (TextPresenter)
- instance vars
- numLines:0 -- number of lines in the list of text
- _font
- end
-
- method init self { class ListBox } #rest args #key \
- font:(theSystemFont) \
- width:(300) \
- list:(#()) ->
- (
- apply nextMethod self target:"" boundary:(new Rect x2:width y2:0) args
- SetDefaultAttr self @alignment @tty
- self.font := font
- self.inset.x := 5
- self.list := list
- )
-
- method fontGetter self {class ListBox} -> self._font
- method fontSetter self {class ListBox} newFont ->
- (
- self._font := newFont
- setDefaultAttr self @font newFont.font
- setDefaultAttr self @leading newFont.leading
- setDefaultAttr self @firstLineLeading (newFont.leading - newFont.descent + 2)
- setDefaultAttr self @size newFont.fontSize
- recalcHeight self
- newFont
- )
-
- method listSetter self {class ListBox} new_list ->
- (
- -- clear out targets
- self.target := "" as String
-
- -- re-build lists
- forEach new_list (item arg -> \
- addMany self.target ((item as String) + "\r")) self
-
- -- select the first line of each column
- self.numLines := new_list.size
- recalcHeight self
- new_list
- )
-
- method listGetter self {class ListBox} ->
- (
- local listText := self.target
- local maxSize := size listText
- local args := #(listText,1,0,maxSize)
- local returnList := #()
- repeat while (FindNthContext args @paragraph) do (
- append returnList (CopyFromTo(listText,args[3],args[4] - 1))
- args[3] := args[4]
- args[4] := maxSize
- )
- returnList
- )
-
- method getListOrdinal self {class ListBox} item ->
- (
- local listText := self.target
- local maxSize := size listText
- local args := #(listText,1,0,maxSize)
- local ord := 1
- repeat while (FindNthContext args @paragraph) do (
- if (item = (CopyFromTo(listText,args[3],args[4] - 1))) do
- return ord
- ord := ord + 1
- args[3] := args[4]
- args[4] := maxSize
- )
- return 0
- )
-
-
- method recalcHeight self {class ListBox} ->
- (
- self.height := self.numLines*self.font.leading + self.font.descent
- )
-
- global upReceiver
- global downReceiver
-
- class ScrollBox(ScrollingPresenter)
- class variables
- mouse:(new MouseDevice)
- instance variables
- doubleClickTime:(getDblClickTime())
- doubleClickAction:(undefined)
- lastTime:0
- lastLine:0
- authordata:(undefined)
-
- downInterest
- upInterest
-
- _selectedLine:0
- selectAction:(undefined)
- selection
-
- maxScroll:0
- stepAmount:0
- pageAmount:0
- scrollDirection
- frame:(new Frame)
- tempPoint:(new Point)
- _list
- end
-
- method init self {class ScrollBox} #rest args #key \
- font:(theSystemFont) ->
- (
- self.stepAmount := font.leading
- apply NextMethod self args
- local targetP := self.targetPresenter
- self.selection := new ListSelection font:font\
- width:self.width parent:targetP
-
- local downInterest := new MouseDownEvent
- self.downInterest := downInterest
- downInterest.eventReceiver := downReceiver
- local upInterest := new MouseUpEvent
- self.upInterest := upInterest
- upInterest.eventReceiver := upReceiver
- downInterest.buttons := upInterest.buttons := @mouseButton1
- downInterest.authordata := upInterest.authordata := self
- downInterest.presenter := upInterest.presenter := self
- downInterest.priority := upInterest.priority := 6
- upInterest.matchedInterest := downInterest
- )
-
- method afterInit self {class ScrollBox} #rest args #key \
- hasScrollBar:(false) \
- value: ->
- (
- apply NextMethod self args
-
- local cp := self.clippingPresenter
- InsetRect cp.boundary 2 2 @mutate
- cp.stationary := true
- cp.fill := WhiteBrush
- self.stationary := true
- if (hasScrollBar) do (
- local vScroll := new SimpleScrollBar orientation:@vertical
- vScroll.directDrag := true
- vScroll.stepAmount := self.stepAmount
- self.vertScrollBar := vScroll
- )
- self.horizScrollBarDisplayed := @none
- if (value != unsupplied) do
- self.value := value
-
- )
-
- method set presentedBy self {class ScrollBox} val ->
- (
- nextMethod self val
- if (val == undefined) then (
- removeEventInterest self.upInterest
- removeEventInterest self.downInterest
- )
- else (
- addEventInterest self.downInterest
- addEventInterest self.upInterest
- )
- val
- )
-
- method recalcRegion self {class ScrollBox} ->
- (
- NextMethod self
- SetBoundary self.frame self.boundary
- )
-
- method downReceiver self {class ScrollBox} theInterest theEvent ->
- (
- local new_selected_line
- self.needsTickle := true
- local tempPoint := self.tempPoint
- setTo tempPoint theEvent.surfaceCoords
- SurfaceToLocal self.targetPresenter tempPoint @mutate
- new_selected_line := ((tempPoint.y / self.stepAmount) as ImmediateInteger) + 1
- selectLine self new_selected_line @dontAction
- @accept
- )
-
- method upReceiver self {class ScrollBox} theInterest theEvent ->
- (
- local selectedLine := self._selectedLine
- self.needsTickle := false
-
- if (selectedLine = self.lastLine) then (
- local doubleClickAction := self.doubleClickAction
- if (((theEvent.timeStamp - self.lastTime) < self.doubleClickTime) and
- doubleClickAction != undefined) then (
- doubleClickAction self.authorData selectedLine
- self.lastTime := 0
- )
- else
- self.lastTime := theEvent.timeStamp
- )
- else (
- self._selectedLine := -1 -- force @doAction to occur
- selectLine self selectedLine @doAction
- self.lastTime := theEvent.timeStamp
- )
-
- self.lastLine := selectedLine
- @accept
- )
-
- method tickle self {class ScrollBox} clock ->
- (
- local tempPoint := self.tempPoint
- local screenCoords := ScrollBox.mouse.currentCoords
- SetTo tempPoint screenCoords
- ScreenToDisplay self.window.displaySurface tempPoint @mutate
- SurfaceToLocal self tempPoint @mutate
- local targetP := self.targetPresenter
-
-
- local bbox := self.clippingPresenter.boundary
- local y1 := bbox.y1
- local y2 := bbox.y2
- local mouseY := tempPoint.y
-
- if (mouseY < y1) then (
- if (self._selectedLine > 0) do
- repeatScrollAction self targetP @up
- )
- else if (mouseY > y2) then
- (
- if (self._selectedLine < self.numLines) do
- repeatScrollAction self targetP @down
- )
- else (
- LocalToSurface self tempPoint @mutate
- SurfaceToLocal targetP tempPoint @mutate
- self.selectedLine := \
- ((tempPoint.y / self.stepAmount) as ImmediateInteger) + 1
- )
- )
-
- method repeatScrollAction self {class ScrollBox} targetPresenter direction ->
- (
- local y := -targetpresenter.y
- local stepAmount := self.stepAmount
- if (direction = @up) then (
- local topPoint := y - stepAmount
- scrollTo self 0 topPoint
- if (topPoint < 0) do topPoint := 0
- self.selectedLine := ((topPoint / stepAmount) as ImmediateInteger) + 1
- )
- else if (direction = @down) do (
- local bottomPoint := y + stepAmount
- scrollTo self 0 bottomPoint
- bottomPoint := bottomPoint + self.height
- local newLine := ((bottomPoint / stepAmount) as ImmediateInteger)
- local numLines := self.numLines
- if (newLine > numLines) do
- newLine := numLines
- self.selectedLine := newLine
- )
- )
-
- method draw self {class ScrollBox} surface clip ->
- (
- NextMethod self surface clip
- drawLoweredFrame self.frame surface clip self.globalTransform
- )
-
- method layout self {class ScrollBox} ->
- (
- ThreadCriticalUp() -- prevent visual jumping of vScroll
- NextMethod self
- local ht := self.height
- self.maxScroll := self.targetPresenter.height - ht
- local cp := self.clippingPresenter
- cp.width := cp.width - 4
- cp.height := cp.height - 4
-
- local stepAmount := self.stepAmount
- -- page a line less than a scrollbox worth
- self.pageAmount := (self.height/stepAmount - 1)*stepAmount
- local vScroll := self.vertScrollBar
- if (vScroll <> undefined) do (
- vScroll.pageAmount := self.pageAmount
- vScroll.y := 2
- vScroll.height := ht - 4
- vScroll.x := vScroll.x - 2
- vScroll.stepAmount := stepAmount
- )
- ThreadCriticalDown()
- self
- )
-
- method selectLine self {class ScrollBox} theLine doAction ->
- (
- if (theLine <> self._selectedLine and theLine > 0 and \
- theLine <= self.numLines ) then (
- ThreadCriticalUp()
- if (doAction = @doAction and self.selectAction != undefined) do
- self.selectAction self.authorData theLine
- selectLine self.selection theLine doAction
- self._selectedLine := theLine
- local lineHt := self.stepAmount
- local startLine := round(-self.targetPresenter.y/lineHt) + 1
- local endLine := \
- (startLine + (self.height - 5 + lineHt)/lineHt - 1) as ImmediateInteger
- if (theLine < startLine or theLine > endLine) do (
- ScrollTo self 0 ((theLine - 1)*lineHt)
- )
- ThreadCriticalDown()
- )
- )
-
- method afterLoading self {class ScrollBox} stream ->
- (
- NextMethod self self stream
- load self.downInterest
- load self.upInterest
- )
-
- method fontSetter self {class ScrollBox} newFont ->
- (
- self.stepAmount := newFont.leading
- if (self.vertScrollBar != undefined) do
- self.vertScrollBar.stepAmount := self.stepAmount
- changeFont self.selection newFont self._selectedLine
- layout self
- newFont
- )
-
-
- method selectedLineGetter self {class ScrollBox} ->
- self._selectedLine
-
- method selectedLineSetter self {class ScrollBox} newLine ->
- (
- selectLine self newLine @doAction
- newLine
- )
-
- method numLinesGetter self {class ScrollBox} ->
- (
- local stepAmount := self.stepAmount
- ((self.targetPresenter.height)/stepAmount) as ImmediateInteger
- )
-
- method widthSetter self {class ScrollBox} newWidth->
- (
- self.selection.width := newWidth
- self.targetPresenter.width := newWidth
- NextMethod self newWidth
- )
-
- method valueGetter self {class ScrollBox} ->
- (
- GetNthKey self._list self._selectedLine
- )
-
- method valueSetter self {class ScrollBox} newValue ->
- (
- local scrollList := self._list
- selectLine self (GetOrdOne scrollList (GetOne scrollList newValue)) @doAction
- self.value
- )
-
- method listGetter self {class ScrollBox} -> self._list
-
- method fillGetter self {class ScrollBox} -> self.clippingPresenter.fill
- method fillSetter self {class ScrollBox} newFill ->
- (
- self.clippingPresenter.fill := newFill
- NextMethod self undefined
- )
-
- class ScrollListBox(ScrollBox)
- end
-
- method init self {class ScrollListBox} #rest args #key \
- boundary: \
- list:(#()) \
- font:(theSystemFont) \
- ->
- (
- local targetPresenter := apply new ListBox \
- width:boundary.width args
- apply NextMethod self boundary:boundary \
- targetPresenter:targetPresenter args
- self.list := list
- )
-
- method fontGetter self {class ScrollListBox} -> self.targetPresenter.font
- method fontSetter self {class ScrollListBox} newFont ->
- (
- self.targetPresenter.font := newFont
- NextMethod self newFont
- )
-
- method listSetter self {class ScrollListBox} newList ->
- (
- self._list := self.targetPresenter.list := newList
- selectLine self 1 @dontAction
- layout self
- newList
- )
-
- method numLinesGetter self {class ScrollListBox} -> self.targetPresenter.numLines
-
- class MultiListBox(ScrollBox)
- instance variables
- numColumns
- end
-
- --sample list: #(#(1,@a),#(2,@b))
- --1 & 2 are in first column, a & b in second. 1&a are across
- --from one another as or 2&b
- method init self {class MultiListBox} #rest args #key \
- boundary: \
- font:(theSystemFont) \
- list:(#()) \
- numColumns: ->
- (
- local targetPresenter := new TwoDMultiPresenter boundary:(copy boundary)
- apply NextMethod self targetPresenter:targetPresenter \
- boundary:boundary args
- if (numColumns = unsupplied) do
- numColumns := size list[1]
- self.numColumns := numColumns
- local columnWidth := self.clippingPresenter.width / numColumns
- for i := 1 to numColumns do (
- local lb := new ListBox width:columnWidth font:font
- lb.x := (columnWidth * (i - 1))
- append targetPresenter lb
- )
- self.list := list
- )
-
- fn setFont aListBox font ->
- (
- if (isAKindOf aListBox ListBox) do
- aListBox.font := font
- )
-
- method fontGetter self {class MultiListBox} ->
- (
- local aListBox := chooseOne self.targetPresenter \
- (a -> isAKindOf a ListBox) undefined
- aListBox.font
- )
-
- method fontSetter self {class MultiListBox} newFont ->
- (
- foreach self.targetPresenter setFont newFont
- NextMethod self newFont
- )
-
- method listSetter self {class MultiListBox} newList ->
- (
- self._list := newList
- selectLine self 1 @dontAction
- local targetP := self.targetPresenter
- for i := 1 to self.numColumns do
- targetP[i+1].list := for j in newList collect j[i]
- targetP.height := targetP[2].height
- layout self
- newList
- )
-
- method widthSetter self {class MultiListBox} val ->
- (
- local origWidth, ratio, targetP, pos
-
- origWidth := self.width
- ratio := val / origWidth
- nextMethod self val
-
- targetP := self.targetPresenter
- pos := 0
- for pres in targetP do (
- if (isAKindOf pres ListBox) do (
- pres.x := pos
- pres.width := ratio * pres.width
- pos := pos + pres.width
- )
- )
- val
- )
-
- method numLinesGetter self {class MultiListBox} ->
- (
- self.targetPresenter[2].numLines
- )
-